#include "mainwindow.h"
#include <iostream>
#include <Windows.h>
#include <QApplication>
#include <QDir>
#include <QFile>
#include <QDebug>
#include <QDateTime>
#include <QMessageBox>
#include "ccrashstack.h"
#include "qchdbghelp.h"
#include <QTextCodec>


LONG CreateCrashHandler(EXCEPTION_POINTERS *pException){

    qDebug() <<"qwe";

    //创建 Dump 文件
    QDateTime CurDTime = QDateTime::currentDateTime();
    QString current_date = CurDTime.toString("yyyy_MM_dd_hh_mm_ss");
    //dmp文件的命名
    QString dumpText = "Dump_"+current_date+".dmp";
    EXCEPTION_RECORD *record = pException->ExceptionRecord;
    QString errCode(QString::number(record->ExceptionCode, 16));
    QString errAddr(QString::number((uintptr_t)record->ExceptionAddress, 16));
    QString errFlag(QString::number(record->ExceptionFlags, 16));
    QString errPara(QString::number(record->NumberParameters, 16));
    HANDLE DumpHandle = CreateFile((LPCWSTR)dumpText.utf16(),
             GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
//    if(DumpHandle != INVALID_HANDLE_VALUE) {
//        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
//        dumpInfo.ExceptionPointers = pException;
//        dumpInfo.ThreadId = GetCurrentThreadId();
//        dumpInfo.ClientPointers = TRUE;
//        //将dump信息写入dmp文件
//        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),DumpHandle, MiniDumpNormal, &dumpInfo, NULL, NULL);
//        CloseHandle(DumpHandle);
//    }
    //创建消息提示
    QMessageBox::warning(NULL,"Dump",QString("ErrorCode%1  ErrorAddr：%2  ErrorFlag:%3 ErrorPara:%4").arg(errCode).arg(errAddr).arg(errFlag).arg(errPara),
        QMessageBox::Ok);
    return EXCEPTION_EXECUTE_HANDLER;
}

long __stdcall callback(_EXCEPTION_POINTERS*   excp)
{
    qDebug() << "123";

    CCrashStack crashStack(excp);
    QString sCrashInfo = crashStack.GetExceptionInfo();

//    TCHAR my_documents[MAX_PATH];
//    SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, my_documents);
//    QString file_path = QString::fromWCharArray(my_documents);
    QDir dir;
    QString file_path = dir.currentPath();

    QDir *folder_path = new QDir;
    bool exist = folder_path->exists(file_path.append("\\MyApp"));
    if(!exist)
    {
        qDebug() << file_path;
        folder_path->mkdir(file_path);
    }
    delete folder_path;
    folder_path = nullptr;

    QString sFileName = file_path + "\\crash.log";
    qDebug() << sFileName;

    QFile file(sFileName);
    if (file.open(QIODevice::WriteOnly|QIODevice::Truncate))
    {
        file.write(sCrashInfo.toUtf8());
        file.close();
    }

    return   EXCEPTION_EXECUTE_HANDLER;
}

using namespace std;

// 如果有调试器，则不会执行这个函数
BOOL bIsBeinDbg = TRUE;
LONG WINAPI UnhandledExcepFilter(PEXCEPTION_POINTERS pExcepPointers){
    qDebug() << "123";
    bIsBeinDbg = FALSE;
    return EXCEPTION_CONTINUE_EXECUTION;
}

int main23(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //获取系统编码
    QTextCodec *codec = QTextCodec::codecForLocale();
    QTextCodec::setCodecForLocale(QTextCodec::codecForLocale());
    //注冊异常捕获函数
//    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CreateCrashHandler);

    SetUnhandledExceptionFilter(callback);
    MainWindow w;
    w.show();
    return a.exec();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

//    LPTOP_LEVEL_EXCEPTION_FILTER Top = SetUnhandledExceptionFilter(UnhandledExcepFilter);


//    // 主动抛出一个异常
//    RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL);


//    SetUnhandledExceptionFilter(callback);
    MainWindow w;
    w.show();

    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);//注冊异常捕获函数

    return a.exec();
}

// Test_Console_1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

int main12(int argc, char *argv[])
{
    // 注册异常处理函数
    LPTOP_LEVEL_EXCEPTION_FILTER Top = SetUnhandledExceptionFilter(UnhandledExcepFilter);

    // 主动抛出一个异常
    RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL);

    if (bIsBeinDbg == TRUE) {
        cout << "发现调试器！" << endl;
    }
    else {
        cout << "没有调试器！" << endl;
    }

main_end:
    getchar();
    return 0;
}


